package top.hmtools.autoConfiguration;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import top.hmtools.RLContext;
import top.hmtools.common.StaticContent;
import top.hmtools.filter.RequestLoggerFilter;

/**
 * 自动配置（作为其它spring boot工程启动入口）
 * @author HyboJ
 *
 */
@Configuration
@ConditionalOnProperty(prefix=StaticContent.CONFIG_PREFIX,value=StaticContent.CONFIG_ITEM_KEY_NAME_ENABLED,matchIfMissing=true)
public class RequestLoggerAutoConfiguration {
	
	protected final Logger logger = LoggerFactory.getLogger(RequestLoggerAutoConfiguration.class);
	
	@Autowired
	private RLContext rlContext;
	
	
	/**
	 * 是否启用
	 */
	@Value("${"+StaticContent.CONFIG_PREFIX+"."+StaticContent.CONFIG_ITEM_KEY_NAME_ENABLED+":true}")
	private boolean enabled;

	/**
	 * 拦截的URL规则
	 */
	@Value("${"+StaticContent.CONFIG_PREFIX+"."+StaticContent.CONFIG_ITEM_KEY_NAME_FILTER_URL_PATTERNS+":/*}")
	private String urlPatterns;
	
	/**
	 * 过滤器名称
	 */
	@Value("${"+StaticContent.CONFIG_PREFIX+"."+StaticContent.CONFIG_ITEM_KEY_NAME_FILTER_NAME+":requestLoggerFilter}")
	private String filterName;
	
	/**
	 * 忽略的uri前缀集合（英文逗号(,)分隔）
	 */
	@Value("${"+StaticContent.CONFIG_PREFIX+"."+StaticContent.CONFIG_ITEM_KEY_NAME_IGNORE_URI_PREFIXES+":}")
	private String ignoreUriPrefix;
	
	/**
	 * 忽略的uri后缀集合（英文逗号(,)分隔）
	 */
	@Value("${"+StaticContent.CONFIG_PREFIX+"."+StaticContent.CONFIG_ITEM_KEY_NAME_IGNORE_URI_SUFFIXES+":}")
	private String ignoreUriSuffix;
	
	/**
	 * 是否启用自定义数据源，
	 * <br>当启用时，则使用本工具包的项目工程会同时存在至少2个数据源，其中一个数据源为本工具包实例化，且本工程使用自己生成的数据源。
	 * <br>不启用时，则使用本工具包所在项目工程所生成的数据源实例。
	 */
	@Value("${"+StaticContent.CONFIG_PREFIX+"_datasource."+StaticContent.CONFIG_ITEM_KEY_NAME_IS_ENABLED_RL_DATASOURCE+":false}")
	private boolean isEnabledRlDataSource;
	
	/**
	 * 批量写入数据到数据库时，单批次最大写入条目数
	 */
	@Value("${"+StaticContent.CONFIG_PREFIX+"."+StaticContent.CONFIG_ITEM_KEY_NAME_BATCH_ITEM_SIZE+":10}")
	private int batchItemSize;
	
	/**
	 * 是否异步将缓存中的日志信息记录写入数据库
	 */
	@Value("${"+StaticContent.CONFIG_PREFIX+"."+StaticContent.CONFIG_ITEM_KEY_NAME_IS_ASYNCHRONOUS+":true}")
	private boolean isAsynchronous;
	
	/**
	 * 线程池维护线程的最少数量
	 */
	@Value("${"+StaticContent.CONFIG_PREFIX+"."+StaticContent.CONFIG_ITEM_KEY_NAME_POOL_CORE_SIZE+":5}")
	private int poolCoreSize;
	
	/**
	 * 线程池维护线程的最大数量
	 */
	@Value("${"+StaticContent.CONFIG_PREFIX+"."+StaticContent.CONFIG_ITEM_KEY_NAME_POOL_MAX_SIZE+":52}")
	private int poolMaxSize;
	
	/**
	 *  线程池所使用的缓冲队列容量
	 */
	@Value("${"+StaticContent.CONFIG_PREFIX+"."+StaticContent.CONFIG_ITEM_KEY_NAME_POOL_WORK_QUEUE_SIZE+":100}")
	private int poolWorkQueueSize;
	
	/**
	 * 线程池维护线程所允许的空闲时间
	 */
	@Value("${"+StaticContent.CONFIG_PREFIX+"."+StaticContent.CONFIG_ITEM_KEY_NAME_POOL_KEEP_ALIVE_TIME+":60}")
	private int poolKeepAliveTime;
	
	/**
	 * 线程池维护线程所允许的空闲时间的单位：NANOSECONDS，MICROSECONDS，MILLISECONDS，SECONDS，MINUTES，HOURS，DAYS
	 */
	@Value("${"+StaticContent.CONFIG_PREFIX+"."+StaticContent.CONFIG_ITEM_KEY_NAME_POOL_KEEP_ALIVE_TIME_UNIT+":SECONDS}")
	private String poolKeepAliveTimeUnit;
	
	/**
	 * 过滤器注册
	 * @param requestLoggerFilter
	 * @return
	 */
	@Bean
	public FilterRegistrationBean filterRegistrationBean(RequestLoggerFilter requestLoggerFilter){
		//过滤器注册实例
		FilterRegistrationBean registrationBean = new FilterRegistrationBean();
		
		//设置过滤器
		registrationBean.setFilter(requestLoggerFilter);
		
		//设置过滤器拦截规则
		registrationBean.addUrlPatterns(this.urlPatterns);
		
		//设置过滤器名称
		registrationBean.setName(this.filterName);
		
		//设置是否启用
		registrationBean.setEnabled(this.enabled);
		
		return registrationBean;
	}
	
	/**
	 * 获取过滤器实例（记录用户请求信息过滤器）
	 * @return
	 */
	@Bean
	public RequestLoggerFilter requestLoggerFilter(){
		return new RequestLoggerFilter(rlContext);
	}
	
	//#########################		getter，setter	#################################

	public RLContext getRlContext() {
		return rlContext;
	}

	public void setRlContext(RLContext rlContext) {
		this.rlContext = rlContext;
	}

	public boolean isEnabled() {
		return enabled;
	}

	public void setEnabled(boolean enabled) {
		this.enabled = enabled;
	}

	public String getUrlPatterns() {
		return urlPatterns;
	}

	public void setUrlPatterns(String urlPatterns) {
		this.urlPatterns = urlPatterns;
	}

	public String getFilterName() {
		return filterName;
	}

	public void setFilterName(String filterName) {
		this.filterName = filterName;
	}

	public String getIgnoreUriPrefix() {
		return ignoreUriPrefix;
	}

	public void setIgnoreUriPrefix(String ignoreUriPrefix) {
		this.ignoreUriPrefix = ignoreUriPrefix;
	}

	public String getIgnoreUriSuffix() {
		return ignoreUriSuffix;
	}

	public void setIgnoreUriSuffix(String ignoreUriSuffix) {
		this.ignoreUriSuffix = ignoreUriSuffix;
	}

	public Logger getLogger() {
		return logger;
	}

	public boolean isEnabledRlDataSource() {
		return isEnabledRlDataSource;
	}

	public void setEnabledRlDataSource(boolean isEnabledRlDataSource) {
		this.isEnabledRlDataSource = isEnabledRlDataSource;
	}

	public int getBatchItemSize() {
		return batchItemSize;
	}

	public void setBatchItemSize(int batchItemSize) {
		this.batchItemSize = batchItemSize;
	}

	public int getPoolCoreSize() {
		return poolCoreSize;
	}

	public void setPoolCoreSize(int poolCoreSize) {
		this.poolCoreSize = poolCoreSize;
	}

	public int getPoolMaxSize() {
		return poolMaxSize;
	}

	public void setPoolMaxSize(int poolMaxSize) {
		this.poolMaxSize = poolMaxSize;
	}

	public int getPoolWorkQueueSize() {
		return poolWorkQueueSize;
	}

	public void setPoolWorkQueueSize(int poolWorkQueueSize) {
		this.poolWorkQueueSize = poolWorkQueueSize;
	}

	public int getPoolKeepAliveTime() {
		return poolKeepAliveTime;
	}

	public void setPoolKeepAliveTime(int poolKeepAliveTime) {
		this.poolKeepAliveTime = poolKeepAliveTime;
	}

	public String getPoolKeepAliveTimeUnit() {
		return poolKeepAliveTimeUnit;
	}

	public void setPoolKeepAliveTimeUnit(String poolKeepAliveTimeUnit) {
		this.poolKeepAliveTimeUnit = poolKeepAliveTimeUnit;
	}

	public boolean isAsynchronous() {
		return isAsynchronous;
	}

	public void setAsynchronous(boolean isAsynchronous) {
		this.isAsynchronous = isAsynchronous;
	}

	@Override
	public String toString() {
		return "RequestLoggerAutoConfiguration [logger=" + logger
				+ ", rlContext=" + rlContext + ", enabled=" + enabled
				+ ", urlPatterns=" + urlPatterns + ", filterName=" + filterName
				+ ", ignoreUriPrefix=" + ignoreUriPrefix + ", ignoreUriSuffix="
				+ ignoreUriSuffix + ", isEnabledRlDataSource="
				+ isEnabledRlDataSource + ", batchItemSize=" + batchItemSize
				+ ", isAsynchronous=" + isAsynchronous + ", poolCoreSize="
				+ poolCoreSize + ", poolMaxSize=" + poolMaxSize
				+ ", poolWorkQueueSize=" + poolWorkQueueSize
				+ ", poolKeepAliveTime=" + poolKeepAliveTime
				+ ", poolKeepAliveTimeUnit=" + poolKeepAliveTimeUnit + "]";
	}
	
	
	
}
